#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <getopt.h>
//#define SERVER_IP	"192.168.0.8"
//#define SERVER_PORT	12345
#define MSG_STR		"Hello ,KAMEN RIDER!"

void print_usage(char *progname)
{
	printf("%s usage: \n",progname);
	//printf("-i(--ipaddr): specify server IP address.\n");
	printf("-p(--port): specify server listen  port.\n");
	printf("-h(--Help): print this help information.\n");

	return;
}

int main (int argc,char *argv[])
{
	int			socket_fd;
	int			client_fd;
	int			rv = -1;
	struct sockaddr_in	server_addr;
	struct sockaddr_in	client_addr;
	socklen_t		cliaddr_len;
	char			buf[1024];
	char			*server_ip;
	int			port;
	int			ch = 0;
	int			on = 1;
	struct option		opts[] = {
		//{"ipaddr",required_argument,NULL,'i'},
		{"port",required_argument,NULL,'p'},
		{"help",no_argument,NULL,'h'},
		{NULL,0,NULL,0}
	};

	
/*	if( argc < 3 )
	{
		printf("Program usage: %s [Server_IP] [Port]\n",argv[0]);
		return -1;
	}
	server_ip = argv[1];
	port = atoi(argv[0]);
*/

	while((ch = getopt_long(argc,argv,"p:h",opts,NULL)) != -1)
	{
		switch(ch)
		{
			/*case 'i':
				server_ip = optarg;
				break;
			*/
			case 'p':
				port = atoi(optarg);
				break;
			case 'h':
				print_usage(argv[0]);
				return 0;
		}
	}

	if( !port )
	{
		print_usage(argv[0]);
		return 0;
	}
	//printf("%s usage: \n",progname);
	socket_fd = socket(AF_INET,SOCK_STREAM,0);
	if(socket_fd < 0)
	{
		printf("Create socket failure: %s\n",strerror(errno));
		return -1;
	}
	printf("Create socket[%d] successful!\n",socket_fd);
	
	setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));

	//bind();
	
	memset(&server_addr,0,sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(port);
	//inet_aton("192.168.0.16",&server_addr.sin_addr);
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	rv = bind(socket_fd,(struct sockaddr *)&server_addr,sizeof(server_addr));
	if(rv<0)
	{
		printf("Socket[%d] bind on port[%d] failure: %s\n",socket_fd,port,strerror(errno));
		return -2;
	}

	listen(socket_fd,13);
	printf("Start to listen on port[%d]\n",port);

	/*rv = connect(socket_fd,(struct sockaddr *)&server_addr,sizeof(server_addr));
	if( rv < 0)
	{
		printf("Connect to server[%s:%d] failure: %s\n",server_ip,port,strerror(errno));
		return -2;
	}
	printf("Connect to server[%s:%d] successful!\n",server_ip,port);
	*/


	while(1)

   {	printf("Start accept new client incoming...\n");
	/*rv = write(socket_fd,MSG_STR,strlen(MSG_STR));
	if( rv < 0 )
	{
		printf("Write to server by socket_fd[%d] failure: %s\n",socket_fd,strerror(errno));
		return -3;
	}
	printf("Write to server by socket_fd[%d] successful!\n",socket_fd);
   }
	*/
	client_fd = accept(socket_fd,(struct sockaddr *)&client_addr,&cliaddr_len);
	if(client_fd < 0)
	{
		printf("Accept new client failure: %s\n",strerror(errno));
		continue;
	}
	printf("Accept new client[%s:%d] with client_fd[%d]\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port),client_fd);

	

	memset(buf,0,sizeof(buf));
	rv = read(client_fd,buf,sizeof(buf));
	if( rv < 0 )
	{
		printf("Read data from client by client_fd[%d] failure: %s\n ",client_fd,strerror(errno));
		return -4;
	}
	else if( rv == 0)
	{
		printf("client_fd[%d] get disconnected\n",client_fd);
		return -5;
	}
	printf("Read %d bytes data from server :%s\n",rv,buf);
	
	rv = write(client_fd,MSG_STR,strlen(MSG_STR));
	if( rv < 0 )
	{
		printf("Write to client by client_fd[%d] failure: %s\n",client_fd,strerror(errno));
		close(client_fd);
		continue;
	}
	printf("Write to client by client_fd[%d] successful!\n",client_fd);
	printf("Close client_fd[%d]\n",client_fd);
	close(client_fd);
   }
	
	close(socket_fd);
}

